﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Linq;
using QuanLyPhongMach.Model;
using QuanLyPhongMach.Platform;
using System.Data.OleDb;

namespace QuanLyPhongMach.Context
{
    public class CBenhNhanContext : DataContext, IContext<CBenhNhan>
    {
        #region Variable
        Table<CBenhNhan> tableBenhNhan;
        #endregion

        #region Constructor
        public CBenhNhanContext(string strConnection) : base (strConnection)
        {
            InitializeTableBenhNhan();
        }

        public CBenhNhanContext(OleDbConnection connection)
            : base(connection)
        {
            InitializeTableBenhNhan();
        }

        private void InitializeTableBenhNhan()
        {
            if (tableBenhNhan != null) return;
            tableBenhNhan = GetTable<CBenhNhan>();
        }
        #endregion

        #region Public Method
        public void LamMoi()
        {
            this.Refresh(RefreshMode.OverwriteCurrentValues, tableBenhNhan);
        }

        /// <summary>
        /// Lấy danh sách của toàn bộ bệnh nhân
        /// </summary>
        /// <returns>List CBenhNhan</returns>
        public List<CBenhNhan> LayDanhSachTatCa()
        {
            var query = from e in tableBenhNhan select e;

            return query.ToList();
        }

        /// <summary>
        /// Lấy thông tin của bênh nhân dựa vào MaBenhNhan tương ứng
        /// </summary>
        /// <param name="maso">MaBenhNhan int</param>
        /// <returns>Thông tin của bệnh nhân CBenhNhan</returns>
        public CBenhNhan LayThongTin(int maso)
        {
            var query = from e in tableBenhNhan where e.MaBenhNhan == maso select e;

            return query.ToList().First();
        }

        /// <summary>
        /// Xóa bệnh nhân dựa vào MaBenhNhan tương ứng
        /// </summary>
        /// <param name="maso">MaBenhNhan int</param>
        public void Xoa(int maso)
        {
            var benhnhan = LayThongTin(maso);

            tableBenhNhan.DeleteOnSubmit(benhnhan);
            this.SubmitChanges();
        }

        /// <summary>
        /// Cập nhật thông tin bệnh nhân dựa vào sai khác so với dữ liệu dựa vào MaBenhNhan tương ứng
        /// </summary>
        /// <param name="obj">Đối tượng CBenhNhan có các thông tin bị thay đổi</param>
        public void CapNhat(CBenhNhan obj)
        {
            this.Connection.Open();

            var command = this.Connection.CreateCommand();
            command.CommandText = String.Format("UPDATE BENHNHAN SET HoTen='{0}', GioiTinh={1}, NamSinh='{2}', DiaChi='{3}' WHERE MaBenhNhan={4}",
                obj.HoTen, obj.GioiTinh.ToString(), obj.ShortNamSinh, obj.DiaChi, obj.MaBenhNhan);
            command.ExecuteNonQuery();

            this.Connection.Close();
            this.Refresh(RefreshMode.OverwriteCurrentValues, tableBenhNhan);
        }

        /// <summary>
        /// Thêm vào bệnh nhân mới
        /// </summary>
        /// <param name="obj">đối tượng CBenhNhan</param>
        public void Them(CBenhNhan obj)
        {
            obj.MaBenhNhan = LayMaSoMoi();
            tableBenhNhan.InsertOnSubmit(obj);
            this.SubmitChanges();
        }

        /// <summary>
        /// Tìm kiếm thông tin bệnh nhân thông qua họ tên
        /// </summary>
        /// <param name="hoten">Cụm từ thuộc họ tên cần tìm kiếm</param>
        /// <returns>List CBenhNhan</returns>
        public List<CBenhNhan> TimTheoHoTen(string hoten)
        {
            var query = from e in tableBenhNhan where e.HoTen.ToLower().Contains(hoten.ToLower()) == true select e;

            return query.ToList();
        }

        /// <summary>
        /// Tìm kiếm thông tin bệnh nhân thông qua địa chỉ
        /// </summary>
        /// <param name="diachi">Địa chỉ cần tìm kiếm</param>
        /// <returns>List CBenhNhan</returns>
        public List<CBenhNhan> TimTheoDiaChi(string diachi)
        {
            var query = from e in tableBenhNhan where e.DiaChi.ToLower().Contains(diachi.ToLower()) == true select e;

            return query.ToList();
        }

        /// <summary>
        /// Lấy mã số mới
        /// </summary>
        /// <returns>Trả về mã số mới</returns>
        public int LayMaSoMoi()
        {
            try
            {
                var query = from e in tableBenhNhan select e.MaBenhNhan;
                return query.ToList().Last() + 1;
            }
            catch { return 1; }
        }

        /// <summary>
        /// Lấy danh sách toàn bộ tên 
        /// </summary>
        /// <returns></returns>
        internal System.Collections.IEnumerable LayDanhSachTenBenhNhan()
        {
            var query = from e in tableBenhNhan select e.HoTen;

            return query.Distinct().ToList() ;
        }

        /// <summary>
        /// Lấy danh sách bệnh nhân theo tên tương tự.
        /// </summary>
        /// <param name="p"></param>
        /// <returns>Trả về danh sách bệnh nhân theo tên</returns>
        internal List<CBenhNhan> LayDanhSachBenhNhanTheoTen(string p)
        {
            p = p.Trim();
            try
            {
                var query = from e in tableBenhNhan where e.HoTen.Contains(p) select e;

                return query.ToList();
            }
            catch { return null; }
        }

        /// <summary>
        /// Lấy danh sách toàn bộ địa chỉ
        /// </summary>
        /// <returns></returns>
        internal System.Collections.IEnumerable LayDanhSachDiaChi()
        {
            var query = from e in tableBenhNhan select e.DiaChi;

            return query.Distinct().ToList() ;
        }

        /// <summary>
        /// Lấy danh sách bệnh nhân nâng cao
        /// </summary>
        /// <param name="tenbenhnhan"></param>
        /// <param name="diachi"></param>
        /// <returns></returns>
        internal List<CBenhNhan> LayDanhSachBenhNhanNangCao(string tenbenhnhan, string diachi, string tenloaibenh, 
            DateTime namsinhtu, DateTime namsinhden, DateTime ngaykhamtu, DateTime ngaykhamden)
        {
            tenloaibenh = tenloaibenh.Trim();
            diachi = diachi.Trim();
            tenloaibenh = tenloaibenh.Trim();

            var tableKhamBenh = GetTable<CKhamBenh>();
            var tableBenh = GetTable<CBenh>();


            var query = from benhnhan in this.tableBenhNhan
                        from khambenh in tableKhamBenh
                        from benh in tableBenh
                        where benhnhan.MaBenhNhan == khambenh.MaBenhNhan && khambenh.MaLoaiBenh == benh.MaLoaiBenh 
                            &&benhnhan.HoTen.Contains(tenbenhnhan)
                            && benhnhan.DiaChi.Contains(diachi)
                            && benh.TenBenh.Contains(tenloaibenh)
                            && khambenh.NgayKham >= ngaykhamtu && khambenh.NgayKham <= ngaykhamden
                            && benhnhan.NamSinh >= namsinhtu && benhnhan.NamSinh <= namsinhden
                        select benhnhan;

            return query.Distinct().ToList();
        }

        internal List<CBenhNhan> LayDanhSachBenhNhanNangCao(string tenbenhnhan, string diachi, string tenloaibenh)
        {
            tenloaibenh = tenloaibenh.Trim();
            diachi = diachi.Trim();
            tenloaibenh = tenloaibenh.Trim();

            var tableKhamBenh = GetTable<CKhamBenh>();
            var tableBenh = GetTable<CBenh>();


            var query = from benhnhan in this.tableBenhNhan
                        from khambenh in tableKhamBenh
                        from benh in tableBenh
                        where benhnhan.MaBenhNhan == khambenh.MaBenhNhan && khambenh.MaLoaiBenh == benh.MaLoaiBenh
                            && benhnhan.HoTen.Contains(tenbenhnhan)
                            && benhnhan.DiaChi.Contains(diachi)
                            && benh.TenBenh.Contains(tenloaibenh)
                        select benhnhan;

            return query.Distinct().ToList();
        }

        internal List<CBenhNhan> LayDanhSachBenhNhanNangCao(DateTime namsinhtu, DateTime namsinhden, DateTime ngaykhamtu, DateTime ngaykhamden)
        {
            var tableKhamBenh = GetTable<CKhamBenh>();
            var tableBenh = GetTable<CBenh>();


            var query = from benhnhan in this.tableBenhNhan
                        from khambenh in tableKhamBenh
                        from benh in tableBenh
                        where benhnhan.MaBenhNhan == khambenh.MaBenhNhan && khambenh.MaLoaiBenh == benh.MaLoaiBenh
                            && khambenh.NgayKham >= ngaykhamtu && khambenh.NgayKham <= ngaykhamden
                            && benhnhan.NamSinh >= namsinhtu && benhnhan.NamSinh <= namsinhden
                        select benhnhan;

            return query.Distinct().ToList();
        }
        #endregion
    }
}
